'************************************************************************************
' Copyright © 2003-2005 Kathleen Dollard
'
' This software is provided 'as-is', without any express or implied warranty. In no 
' event will the author be held liable for any damages arising from the use of this
' software.
' 
' You may use this software for any purpose, including commercial applications, 
' and you may redistribute this software as part of application delivery: however, 
' this copyright notice may not be removed and you may not otherwise redistribute 
' this software directly other than providing a link to wwww.gendotnet.com. 
'
' You may alter this software to better server your needs (I'd like to hear about your 
' changes in order to make the software better). If you alter the softwre, you must  
' clearly mark it as altered and must not be misrepresented as the original software.
' nor wholly your original work.
'*************************************************************************************
Option Strict On
Option Explicit On 

Imports System
Imports CodeSmith.Engine

Namespace KADGen.CodeGenerationSupport
   Public Class CodeSmithGeneration
      Inherits MultiPass

      'Public Const MetadataAll As String = "MetadataAll"             ' Type = "MetadataWrapper.All"
      'Public Const MetadataDbs As String = "MetadataDbs"             ' Type = "DbsDataStructureCollection"
      'Public Const MetadataMapping As String = "MetadataMapping"     ' Type = "MapMapping"
      'Public Const MetadataAssembly As String = "MetadataAssembly"   ' Type = "GenAssembly"
      'Public Const MetadataBuild As String = "MetadataBuild"         ' Type = "BuildBuild"
      'Public Const MetadataTable As String = "MetadataTable"         ' Type = "DbsTable"
      'Public Const MetadataView As String = "MetadataView"           ' Type = "DbsView"
      'Public Const MetadataObjectDef As String = "MetadataObjectDef" ' Type = "MapObjectDef"
      'Public Const MetadataObject As String = "MetadataObject"       ' Type = "GenObject"
      'Public Const MetadataSPSet As String = "MetadataSPSet"         ' Type = "BuildSPSet"


#Region "Class level declarations"
      'Private mMetadata As MetadataWrapper.All
      'Private mCodeSmithTemplate As CodeTemplate
      'Private mInputFileName As String
      'Private mTemplateFileName As String
#End Region

#Region "Public properties and methods"
      Public Sub Run( _
                     ByVal node As Xml.XmlNode, _
                     ByVal runUtility As RunUtility, _
                     ByVal statusDirective As IStatusDirective)
         Dim obj As System.Runtime.Remoting.ObjectHandle = Nothing
         Dim basePath As String = IO.Path.GetDirectoryName(Windows.Forms.Application.ExecutablePath)
         Dim testFile As String
         testFile = IO.Path.Combine(basePath, "../../CodeSmithSupport/bin/Debug/CodeSmithSupport.dll")
         If IO.File.Exists(testFile) Then
            obj = System.Activator.CreateInstanceFrom(testFile, "KADGen.CodeSmithSupport.CodeSmithGeneration")
         End If
         testFile = IO.Path.Combine(basePath, "../../CodeSmithSupport/bin/CodeSmithSupport.dll")
         If IO.File.Exists(testFile) Then
            obj = System.Activator.CreateInstanceFrom(testFile, "KADGen.CodeSmithSupport.CodeSmithGeneration")
         End If
         testFile = IO.Path.Combine(basePath, "CodeSmithSupport.dll")
         If IO.File.Exists(testFile) Then
            obj = System.Activator.CreateInstanceFrom(testFile, "KADGen.CodeSmithSupport.CodeSmithGeneration")
         End If
         If obj Is Nothing Then
            Throw New System.Exception("Could not find CodeSmithSupport.dll. Please copy this file into your application directory")
         End If
         Dim codeSmithSupport As Object = obj.Unwrap()
         Dim methodInfo As Reflection.MethodInfo = codeSmithSupport.GetType().GetMethod("Run", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Static Or Reflection.BindingFlags.IgnoreCase Or Reflection.BindingFlags.Public Or Reflection.BindingFlags.NonPublic)
         If Not methodInfo Is Nothing Then
            methodInfo.Invoke(codeSmithSupport, New Object() {node, runUtility, statusDirective})
         End If
      End Sub

      'Public Sub Run( _
      '                ByVal node As Xml.XmlNode, _
      '                ByVal runUtility As RunUtility, _
      '                ByVal statusDirective As IStatusDirective)
      '   Dim codeSmithGenDirective As CodeGenerationSupport.ICodeSmithGenerationDirective
      '   Dim multiPassDirective As CodeGenerationSupport.IMultiPassDirective

      '   codeSmithGenDirective = CType(node, CodeGenerationSupport.ICodeSmithGenerationDirective)
      '   multiPassDirective = CType(node, CodeGenerationSupport.IMultiPassDirective)
      '   Try
      '      OpenXmlFile(codeSmithGenDirective, statusDirective)
      '      OpenTemplateFile(codeSmithGenDirective, statusDirective)
      '      Me.MultiPass(multiPassDirective, _
      '               Nothing, Nothing, _
      '               AddressOf CodeSmithGenerationCallBack, _
      '               statusDirective, _
      '               runUtility)
      '   Catch ex As System.Exception
      '      Diagnostics.Debug.WriteLine("")
      '      ' Exception should already be recorded
      '   End Try
      'End Sub
#End Region

      '#Region "Protected properties and methods"

      '#End Region

      '#Region "Private properties and methods"
      '      Private Sub OpenXmlFile( _
      '               ByVal codeSmithGen As CodeGenerationSupport.ICodeSmithGenerationDirective, _
      '               ByVal statusDirective As CodeGenerationSupport.IStatusDirective)
      '         Dim statusOutput As CodeGenerationSupport.IStatusOutput
      '         Const source As String = "XsltGeneration.OpenXmlFile"
      '         If (mMetadata Is Nothing Or mInputFileName Is Nothing) _
      '                  OrElse mInputFileName <> codeSmithGen.CodeSmith.InputFileName Then
      '            Try

      '               mMetadata = MetadataAdapter.All.GetWrapper(codeSmithGen.CodeSmith.InputFileName)
      '            Catch ex As System.Exception
      '               statusOutput = statusDirective.AddStatusOutput( _
      '                        "<none>", _
      '                        FileTreatment.Unknown)
      '               statusOutput.AddStatusFailure(source, _
      '                        "Failure opening input metadata file", ex)
      '               Throw
      '            End Try
      '         End If
      '      End Sub

      '      Private Sub OpenTemplateFile( _
      '               ByVal codeSmithGen As CodeGenerationSupport.ICodeSmithGenerationDirective, _
      '               ByVal statusDirective As CodeGenerationSupport.IStatusDirective)
      '         Const source As String = "CodeSmithGeneration.OpenXsltFile"
      '         Dim statusOutput As CodeGenerationSupport.IStatusOutput
      '         ' Cache and reuse results
      '         If (mCodeSmithTemplate Is Nothing Or mTemplateFileName Is Nothing) _
      '                 OrElse mTemplateFileName <> codeSmithGen.CodeSmith.CodeSmithTemplateFileName Then
      '            Try
      '               mTemplateFileName = codeSmithGen.CodeSmith.CodeSmithTemplateFileName
      '               Dim compiler As New CodeTemplateCompiler(mTemplateFileName)
      '               compiler.Compile()

      '               If compiler.Errors.Count = 0 Then
      '                  ' KAD: TODO: Report errors
      '                  mCodeSmithTemplate = compiler.CreateInstance()
      '                  'Dim runTemplate As RunTemplateBase = TryCast(mCodeTemplate, RunTemplateBase)
      '                  'If runTemplate IsNot Nothing Then
      '                  '   runTemplate.TemplateInfo = Me
      '                  'End If
      '               Else
      '                  Throw New System.Exception("CodeSmith template compilation failure")
      '               End If
      '            Catch ex As System.Exception
      '               statusOutput = statusDirective.AddStatusOutput( _
      '                        "<none>", _
      '                        FileTreatment.Unknown)
      '               statusOutput.AddStatusFailure(source, _
      '                        "Failure loading CodeSmith template (Filename=" & _
      '                              codeSmithGen.CodeSmith.CodeSmithTemplateFileName, ex)
      '               Throw
      '            End Try
      '         End If
      '      End Sub

      '      Private Function CodeSmithGenerationCallBack( _
      '               ByVal outputFileName As String, _
      '               ByVal multiPassDirective As CodeGenerationSupport.IMultiPassDirective, _
      '               ByVal nodeSelect As Xml.XmlNode, _
      '               ByVal runUtility As CodeGenerationSupport.RunUtility, _
      '               ByVal statusOutput As CodeGenerationSupport.IStatusOutput) _
      '               As IO.Stream
      '         Dim propertyInfos As Reflection.PropertyInfo() = mCodeSmithTemplate.GetProperties()
      '         Dim name As String = Utility.xmlHelpers.GetAttributeOrEmptyString(nodeSelect, "Name")

      '         For Each propertyInfo As Reflection.PropertyInfo In propertyInfos
      '            If propertyInfo.Name.ToLower() = MetadataAll.ToLower Then
      '               mCodeSmithTemplate.SetProperty(propertyInfo.Name, mMetadata)
      '            End If
      '            If propertyInfo.Name.ToLower() = MetadataDbs.ToLower Then
      '               mCodeSmithTemplate.SetProperty(propertyInfo.Name, mMetadata.DataStructures)
      '            End If
      '            If propertyInfo.Name.ToLower() = MetadataAssembly.ToLower Then
      '               mCodeSmithTemplate.SetProperty(propertyInfo.Name, mMetadata.Assembly)
      '            End If
      '            If propertyInfo.Name.ToLower() = MetadataBuild.ToLower Then
      '               mCodeSmithTemplate.SetProperty(propertyInfo.Name, mMetadata.Build)
      '            End If
      '            If propertyInfo.Name.ToLower() = MetadataMapping.ToLower Then
      '               mCodeSmithTemplate.SetProperty(propertyInfo.Name, mMetadata.Mapping)
      '            End If
      '            If propertyInfo.Name.ToLower() = MetadataTable.ToLower Then
      '               mCodeSmithTemplate.SetProperty(propertyInfo.Name, mMetadata.DataStructures.GetTable(name))
      '            End If
      '            If propertyInfo.Name.ToLower() = MetadataView.ToLower Then
      '               mCodeSmithTemplate.SetProperty(propertyInfo.Name, mMetadata.DataStructures.GetView(name))
      '            End If
      '            If propertyInfo.Name.ToLower() = MetadataObject.ToLower Then
      '               mCodeSmithTemplate.SetProperty(propertyInfo.Name, mMetadata.Assembly.GetObject(name))
      '            End If
      '            If propertyInfo.Name.ToLower() = MetadataSPSet.ToLower Then
      '               mCodeSmithTemplate.SetProperty(propertyInfo.Name, mMetadata.Build.GetSPSet(name))
      '            End If
      '            If propertyInfo.Name.ToLower() = MetadataObjectDef.ToLower Then
      '               mCodeSmithTemplate.SetProperty(propertyInfo.Name, mMetadata.Mapping.GetObjectDef(name))
      '            End If
      '            If propertyInfo.Name.ToLower() = "name" Then
      '               mCodeSmithTemplate.SetProperty(propertyInfo.Name, name)
      '            End If
      '         Next
      '         Return CodeGenerationSupport.CodeSmithSupport.GenerateViaCodeSmith( _
      '                              mCodeSmithTemplate, mMetadata, outputFileName, _
      '                              multiPassDirective.OutputRule.OutputFileType)
      '      End Function

      '#End Region
   End Class
End Namespace